package k3_annotation.demo03;

import k1_jdbc.tool.ConnectionTool;
import k1_jdbc.tool.Const;
import k2_reflection.demo02.Customer;
import k2_reflection.demo02.Teachers;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;

public class ObjectOperation {

    public static void insertObject(Object object){

        Connection conn = null;
        PreparedStatement ps = null;

        //需要添加到表中的属性的索引的列表
        List<Integer> toAddFieldIndexList = new ArrayList<>();

        String tableName= "";
        String fieldName= "";

        //获取对象的Class类型
        Class objClass = object.getClass();

        //判断当前对象对应的类是否存在 Table 这个注解，如果有，这个注解的value值作为表名，如果没有，类名直接作为表名
        if (objClass.isAnnotationPresent(Table.class)) {
            Table table = (Table)objClass.getDeclaredAnnotation(Table.class);
            tableName = table.value();
        }else{
            //获取当前对象的类名，直接作为sql语句的表名
            tableName = objClass.getSimpleName().toLowerCase();
        }

        try {
            Class.forName(Const.DRIVER);

            conn = DriverManager.getConnection(Const.URL_TEST, Const.USERNAME, Const.PASSWORD);

            //insert into stu(name,age) values(?,?);
            //用StringBuffer拼接sql语句
            StringBuffer sb = new StringBuffer("insert into "+tableName+"(");

            //获取当前对象的类中所有的属性数组
            Field[] fields = objClass.getDeclaredFields();

            //遍历所有的属性
            for (int i = 0; i < fields.length; i++) {
                //获取遍历到当前位置的那个属性
                Field currentField = fields[i];
                //判断当前这个属性是否有 PrimaryKey 这个注解
                if (currentField.isAnnotationPresent(PrimaryKey.class)) {
                    PrimaryKey primaryKeyAnnotation = currentField.getDeclaredAnnotation(PrimaryKey.class);
                    if (primaryKeyAnnotation.autoIncrement()) {
                        continue;
                    }
                }

                //如果当前属性为非主键或当前字段是主键但非自增长都是需要添加的列
                toAddFieldIndexList.add(i);

                //如果有Column注解，要读取Column注解中的value的值作为要添加的字段名
                if(currentField.isAnnotationPresent(Column.class)){
                    Column columnAnnotation = currentField.getDeclaredAnnotation(Column.class);
                    fieldName = columnAnnotation.value();
                }else{
                    //如果没有Column直接，直接读取属性名充当要添加的字段名
                    fieldName = currentField.getName().toLowerCase();
                }
                sb.append(fieldName+ (i==fields.length-1?")":","));
            }

            sb.append(" values(");

            //有多少个需要添加的属性，就有多少个问号
            for (int i = 1; i <= toAddFieldIndexList.size() ; i++) {
                sb.append(i==toAddFieldIndexList.size()?"?)":"?,");
            }

            System.out.println(sb.toString());

            //对这个sql语句进行预处理
            ps = conn.prepareStatement(sb.toString());

            //遍历所有的属性，获取这个对象中每个属性的值，分别设置相应问号
            for (int i = 0; i < toAddFieldIndexList.size() ; i++) {
                //获取数组中的第 i 个属性
                Field currentField = fields[toAddFieldIndexList.get(i)];
                //把所有的属性都设置为 私有 允许访问
                currentField.setAccessible(true);
                //从对象中获取相应属性的值
                Object fieldValue = currentField.get(object);
                //对相应的问号进行赋值
                ps.setObject(i+1,fieldValue);
            }

            int result = ps.executeUpdate();

            System.out.println(result);

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            ConnectionTool.closed(conn,ps);
        }
    }

    public static void main(String[] args) {

        Teachers teacher = new Teachers(101,"tom");
        Customer customers = new Customer("jerry",20,"hrb",100);


        insertObject(customers);
    }

}
